home *** CD-ROM | disk | FTP | other *** search
- #include <alloc.h>
- #include <bios.h>
- #include <dos.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "csimint.h"
-
-
- int start_kb_process(void(*task)(void),int stacksize)
- {
- int proc_id;
- set_kb_process = 1;
- proc_id = start_process(task,stacksize);
- set_kb_process = 0;
- return(proc_id);
- }
-
-
- int start_process(void(*task)(void),int stacksize)
- {
- char *stack;
- struct _simprocessT *process;
- int *off_seg=(int *)&stack;
- unsigned int stackbytes;
- int oldinit;
-
- /* Check to see if tack handler has been installed*/
-
- if(getvect(_INTRPT_)!=task_handler)
- /* if it has not been installed, attempt to */
-
- if(install_handler())
- /* if it doesn't install, report error and exit */
- {
- printf("error installing task handler \n");
- exit_processing(1);
- }
-
- if(stacksize > 0x0fdf)
- /* Max stack size in paragraphs (SEGMENT counts)*/
- {
- printf("stack size error: proc id : %d",totalprocs);
- exit_processing(2);
- }
-
- stackbytes = stacksize * 16;
-
- /* Setup Process header and stack */
-
- process =
- (struct _simprocessT *)
- calloc(sizeof(struct _simprocessT) + stackbytes,1);
-
- /* make sure there was enough memory */
- if(process==NULL)
- return(2);
-
- stack = (char *)(process+1);
-
- /* 'Normalize' the bottom of stack pointer, that is
- make sure the offset is less then 16, as would be
- the case if the program where compiled in the huge
- memory model */
-
- if(off_seg[0]>16)
- for(;off_seg[0]>16;off_seg[1]++,off_seg[0]-=16);
-
- /* remember, the stack actually starts high and
- builds its way down, so put the pointer at the top.*/
-
- stack += stackbytes - 1;
-
- /* finish setup of stack and base pointers */
-
- process->reg_sp = FP_OFF(stack);
- process->reg_ss = FP_SEG(stack);
-
- process->reg_bp = FP_OFF(stack);
-
- process->proc_id = totalprocs++;
- process->init = 1;
-
- /* Setup start jump */
- process->reg_cs = FP_SEG(task);
- process->reg_ip = FP_OFF(task);
-
- /* link into current processes */
- if(processlist==NULL)
- {
- processlist = process;
- processlist->next = process;
- processlist->prev = process;
- }
- else
- {
- process->prev = processlist;
- process->next = processlist->next;
- process->next->prev = process;
- processlist->next = process;
- processlist = process;
- }
- if(set_kb_process)
- kbprocess = processlist;
-
- /* make sure we can get back to where we were... */
- glbl_ss = _SS;
- glbl_sp = _SP;
- glbl_bp = _BP;
- oldinit = _sim_init_val;
-
- /* tell the task handler what routine the process uses */
-
- glbl_fc = task;
-
- /* tell the task handler that this proc is initing */
-
- _sim_init_val=1;
-
- /* set up the new stak and base pointers and ... */
- _SS = process->reg_ss;
- _SP = process->reg_sp;
- _BP = process->reg_bp;
-
- /* have the task_handle do the rest */
- geninterrupt(_INTRPT_);
-
- _SS = glbl_ss;
- _SP = glbl_sp;
- _BP = glbl_bp;
- glbl_fc = NULL;
- _sim_init_val = oldinit;
- processlist = processlist->prev;
- return(0);
-
- }
-
-
- void stop_process(int process_id)
- {
- struct _simprocessT *process;
- int go;
-
- go = 1;
- process = processlist;
-
- while(go)
- {
- if(process_id == process->proc_id)
- {
- process->status.kill_flag = 1;
- process->start_time = _sim_system_time;
- go = 0;
- }
- if(process->next == processlist)
- {
- if(go)
- printf("\nattempted to stop non-existant proc\n");
- go = 0;
- }
- else
- {
- process = process->next;
- }
- }
- }
-
-
-
- void sim_start(void)
- {
- _sim_init_val=0;
- _last_update_time = *systimer;
- geninterrupt(_INTRPT_);
- }
-
-
- void exit_processing(int condition)
- {
- struct _simprocessT *pholder;
- setvect(_INTRPT_,old_vector);
- printf("Exit processing, code : %d\n",condition);
- processlist->prev->next = NULL;
- do
- {
- pholder = processlist;
- processlist = processlist->next;
- free(pholder);
- } while(processlist!=NULL);
- exit(condition);
- }
-
-
- int install_handler(void)
- {
- void *new_vector;
-
- _sim_init_val=2;
- old_vector = getvect(_INTRPT_);
- setvect(_INTRPT_,task_handler);
- new_vector = getvect(_INTRPT_);
- if(new_vector==old_vector)
- return(1);
- return(0);
- }
-
-
- void interrupt task_handler( unsigned bp,unsigned di,unsigned si,
- unsigned ds,unsigned es,unsigned dx,
- unsigned cx,unsigned bx,unsigned ax,
- unsigned ip,unsigned cs,unsigned flags)
- {
- int notfound;
- struct _simprocessT *procpntr;
-
- if(_sim_init_val==2)
- /* if this ever happens, it means that the task handler
- was installed before it should have been, so de-install
- it and stop the program */
- {
- exit_processing(10);
- }
- if(_sim_init_val==0) /* sim_start has been run */
- {
- processlist->reg_bp = _BP;
- processlist->reg_sp = _SP;
- processlist->reg_ss = _SS;
-
- if(processlist->status.kill_flag)
- {
- if(processlist == kbprocess)
- /* You can,t kill the kbproc */
- processlist->status.kill_flag = 0;
- else
- {
- if(processlist->next == processlist)
- /* no more procs */
- exit_processing(20);
-
- /* break list */
- processlist->prev->next = processlist->next;
-
- /* move in front of break */
- processlist = processlist->prev;
-
- /* free dead proc */
- free(processlist->next->prev);
-
- /* fix break */
- processlist->next->prev = processlist;
- }
- }
-
- if((kbprocess!= NULL)&&(bioskey(1)))
- processlist = kbprocess;
- else
- {
- if(_sim_time_ratio != 0.0)
- {
- for(notfound = 1;notfound;)
- {
- if((kbprocess != NULL)&&(bioskey(1)))
- {
- processlist = kbprocess;
- notfound = 0;
- }
- else
- {
- processlist = processlist->next;
- if((*systimer - _last_update_time)>
- (1/_sim_time_ratio))
- {
- _sim_system_time +=
- (*systimer -
- _last_update_time) *
- _sim_time_ratio;
- _last_update_time = *systimer;
- }
- if((processlist->start_time <=
- _sim_system_time)&&
- (processlist->status.wait_flag==0))
- notfound = 0;
- }
- }
- _sim_system_time = processlist->start_time;
- }
- else
- {
- if(processlist->status.wait_flag)
- {
- for(procpntr=processlist->next;
- procpntr&&
- (procpntr->status.wait_flag)&&
- (procpntr->status.kill_flag);)
- {
- procpntr = procpntr->next;
- if(procpntr == processlist)
- procpntr = NULL;
- }
- if(procpntr == NULL)
- {
- fprintf(stderr,"waitlock\n");
- exit_processing(1);
- }
- _sim_system_time = procpntr->start_time;
- }
- else
- _sim_system_time = processlist->start_time;
- procpntr = processlist->next;
- while(procpntr!= processlist)
- {
- if((!procpntr->status.wait_flag)&&
- (_sim_system_time > procpntr->start_time))
- _sim_system_time = procpntr->start_time;
- procpntr = procpntr->next;
- }
- processlist = processlist->next;
- while((processlist->status.wait_flag||
- processlist->status.kill_flag)||
- (processlist->start_time > _sim_system_time))
- processlist = processlist->next;
- _last_update_time = *systimer;
- }
- }
-
- CurrentTime = _sim_system_time/18.2;
- disable();
- _SP = processlist->reg_sp;
- _SS = processlist->reg_ss;
- _BP = processlist->reg_bp;
- enable();
-
- if(processlist->init==1)
- /* process is in its first step, so initialize it */
- {
- ax = processlist->reg_ax;
- bx = processlist->reg_bx;
- cx = processlist->reg_cx;
- dx = processlist->reg_dx;
- es = processlist->reg_es;
- ds = processlist->reg_ds;
- si = processlist->reg_si;
- di = processlist->reg_di;
- bp = processlist->reg_bp;
- ip = processlist->reg_ip;
- cs = processlist->reg_cs;
- flags = processlist->reg_flag;
- processlist->init = 0;
- }
- }
- else /* sim_start has not been run */
- {
- if(_sim_init_val==1)
- {
- processlist->reg_ax = ax;
- processlist->reg_bx = bx;
- processlist->reg_cx = cx;
- processlist->reg_dx = dx;
- processlist->reg_es = es;
- processlist->reg_ds = ds;
- processlist->reg_si = si;
- processlist->reg_di = di;
- processlist->reg_ip = FP_OFF(glbl_fc);
- processlist->reg_cs = FP_SEG(glbl_fc);
- processlist->reg_flag = flags;
- processlist->reg_bp = _BP;
- processlist->reg_sp = _SP;
- processlist->reg_ss = _SS;
- processlist->init = 1;
- cs = cs;
- ip = ip;
- bp = bp;
- }
- }
- }
-
-
- int set_time_ratio (float ratio)
- {
- _sim_time_ratio = ratio;
- return(0);
- }
-
-
- int my_process_id(void)
- {
- return(processlist->proc_id);
- }
-
-
- int wait_until_time (long unsigned starttime)
- {
- if(starttime < (_sim_system_time/18.2))
- {
- printf("Waiting for a time that is past in %d",
- processlist->proc_id);
- exit_processing(-1);
- }
- wait_for_time((float)(starttime*18.2 - _sim_system_time)/18.2);
- return(0);
- }
-
-
- int wait_for_time (float delaytime)
- {
- if(_sim_time_ratio == 0)
- {
- processlist->start_time =
- _sim_system_time + delaytime*18.2;
- }
- else
- processlist->start_time =
- _sim_system_time + (long)(18.2 * delaytime);
-
- geninterrupt(_INTRPT_);
- return(0);
- }
-
-
- int init_post (char *postname)
- {
- struct _postT *post;
-
- for(post = postlist;post != NULL;post = post->next)
- {
- if(strcmp((char *)&post->name,postname)==0)
- return(post->handle);
- }
- post = (struct _postT *)calloc(sizeof(struct _postT),1);
- if(post==NULL)
- return(-1);
-
- post->handle = totalposts++;
- post->value = NULL;
- strcpy((char *)&post->name,postname);
-
- post->waiting = calloc(1,sizeof(void *));
- post->waiting[0] = NULL;
-
- post->next = postlist;
- post->prev = NULL;
-
- postlist->prev = post;
- postlist = post;
- return(post->handle);
- }
-
-
- int set_post (int posthandle,void *pointer)
- {
- struct _postT *post;
- struct _simprocessT *procpntr;
- int loop;
- for(post = postlist;post != NULL;post = post->next)
- {
- if(post->handle==posthandle)
- {
- if(post->value != NULL)
- {
- wait_for_time(0);
- if(post->value != NULL)
- return(post->handle);
- }
- if(post->waiting[0] != NULL)
- {
- post->waiting[0]->status.wait_flag = 0;
- post->waiting[0]->start_time = _sim_system_time;
- loop = 0;
- procpntr = processlist->next;
- while(procpntr != processlist)
- {
- if((procpntr->status.wait_flag)&&
- (procpntr->waitpost == post))
- {
- post->waiting[loop] = procpntr;
- loop++;
- }
- procpntr = procpntr->next;
- }
- post->waiting[loop] = NULL;
- }
- post->value = pointer;
- wait_for_time(0);
- return(0);
- }
- }
- return(-posthandle);
- }
-
-
- void *get_post (int posthandle)
- {
- struct _postT *post;
- void *ret;
-
- for(post = postlist;post != NULL;post = post->next)
- {
- if(post->handle==posthandle)
- {
- ret = post->value;
-
- if(ret==NULL)
- return(ret);
-
- post->value = NULL;
- return(ret);
- }
- }
- return(NULL);
- }
-
-
- void *wait_post (int posthandle)
- {
- struct _postT *post;
- void *ret;
- int loop;
-
- for(post = postlist;post != NULL;post = post->next)
- {
- if(post->handle==posthandle)
- {
- ret = post->value;
-
- if(ret==NULL)
- {
- for(loop=0;post->waiting[loop];)
- loop++;
- post->waiting =
- realloc(post->waiting,(loop+2)*sizeof(void*));
- post->waiting[loop] = processlist;
- post->waiting[loop+1] = NULL;
- while(ret == NULL)
- {
- processlist->status.wait_flag = 1;
- processlist->waitpost = postlist;
- wait_for_time(0);
- ret = post->value;
- post->value = NULL;
- }
- processlist->waitpost = NULL;
- return(ret);
- }
-
- post->value = NULL;
- return(ret);
- }
- }
- return(NULL);
- }
-